
/*
	StatusLine( .iInflictorID = ,
				.vStart = ,
				.vEnd = ,
				.iStatus = STATUS_,
				.fRadius = ,
				.iAmount = 
				);
*/

PM_FUNC_NORM_ATTRIB StatusLine( Int:iInflictorID, Vector:vStart[3], Vector:vEnd[3], PM_STATUS:iStatus, Float:fRadius, Int:iAmount )
{
	pokemod_funcstart_debug( "StatusLine" );

	new CsTeams:iTeam = cs_get_user_team( iInflictorID );

	new Vector:vPlayerOrigin[3], Int:iDistance;
	new Int:iAffected;

	LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
	{
		if ( iTeam == cs_get_user_team( iPlayer ) )
			continue;

		EntityGetOrigin( iPlayer, vPlayerOrigin );

		iDistance = get_distance_to_line( vStart, vEnd, vPlayerOrigin );

		if ( 0.0 <= iDistance <= fRadius )
		{
			if ( StatusApply( iPlayer, iInflictorID, iStatus, iAmount ) )
				iAffected++;
		}
	}

	pokemod_funcend_debug( "StatusLine" );

	return iAffected;
}

/*
	StatusAoE( .iInflictorID = ,
				.cOrigin = ,
				.iStatus = STATUS_,
				.fRadius = ,
				.iAmount = 
				);
*/

PM_FUNC_NORM_ATTRIB StatusAoE( Int:iInflictorID, Coord:cOrigin[3], PM_STATUS:iStatus, Float:fRadius, Int:iAmount )
{
	pokemod_funcstart_debug( "StatusAoE" );

	new CsTeams:iTeam = cs_get_user_team( iInflictorID );

	new Coord:cPlayerOrigin[3], Int:iDistance;
	new Int:iAffected;

	LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
	{
		if ( iTeam == cs_get_user_team( iPlayer ) )
			continue;

		get_user_origin( iPlayer, cPlayerOrigin );

		iDistance = get_distance( cPlayerOrigin, cOrigin );

		if ( 0.0 <= iDistance <= fRadius )
		{
			if ( StatusApply( iPlayer, iInflictorID, iStatus, iAmount ) )
				iAffected++;
		}
	}

	pokemod_funcend_debug( "StatusAoE" );

	return iAffected;
}

/*
	StatusApply( .iPlayer = ,
				.iInflictorID = ,
				.iStatus = STATUS_,
				.iAmount = 
				);
*/
PM_FUNC_NORM_ATTRIB StatusApply( Int:iPlayer, Int:iInflictorID, PM_STATUS:iStatus, Int:iAmount )
{
	new Int:iOld = g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_AMOUNT ];
	if ( iOld == -1 || ( !iOld && iAmount < 0 ) )
		return false;

	pokemod_funcstart_debug( "StatusApply" );

	if ( iAmount > 0 )
	{
		if ( !iOld )
		{
			//Increase amount by one because it will be reduced by one immediately in StatusEffect
			iAmount++;
		}

		g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_INFLICTOR ] = iInflictorID;
	}

	g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_AMOUNT ] = max( 0, iOld + iAmount );

	if ( !iOld && iAmount > 0 )
	{
		PlayerAddInfo( iPlayer, PINFO_STATUS_EFFECT, 1 );

		new const String:szStatusName[ PM_STATUS ][] = {
			"Burned",
			"Slowed",
			"Poisoned",
			"put to Sleep",
			"Frozen",
			"Confused",
			"Paralyzed"
		}

		DHudEventMessage( iPlayer, "You have been %s by %s", szStatusName[ iStatus ], PlayerToName( iInflictorID ) );

		if ( iPlayer != iInflictorID )
			DHudEventMessage( iInflictorID, "%s has been %s", PlayerToName( iPlayer ), szStatusName[ iStatus ] );

		new Int:iParm[ 2 ];
		iParm[ 0 ] = iPlayer;
		iParm[ 1 ] = _:iStatus;
		StatusEffect( iParm );

		SkillCallType( CALL_STATUS_CHANGE, iPlayer );
	}

	pokemod_funcend_debug( "StatusApply" );

	return true;
}

PM_FUNC_NORM_ATTRIB StatusCure( Int:iPlayer, PM_STATUS:iStatus, bool:bShowMessage )
{
	pokemod_funcstart_debug( "StatusCure" );

	g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_AMOUNT ] = -1;

	new const String:szStatusName[ PM_STATUS ][] = {
		"Burn",
		"Slow",
		"Poison",
		"Sleep",
		"Frost",
		"Confusion",
		"Paralysis"
	}

	if ( bShowMessage )
		DHudEventMessage( iPlayer, "You have been cured of %s for the round", szStatusName[ iStatus ] );

	pokemod_funcend_debug( "StatusCure" );

	return 1;
}

PM_FUNC_PUBLIC_ATTRIB StatusEffect( Int:iParm[ 2 ] )
{
	new Int:iPlayer = iParm[ 0 ];
	new PM_STATUS:iStatus = PM_STATUS:iParm[ 1 ];

	if ( !is_user_alive( iPlayer ) )
	{
		g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_AMOUNT ] = 0;

		if ( iStatus == STATUS_ASLEEP )
		{
			EffectScreenFlash( iPlayer,
							.iRed = 0,
							.iGreen = 0,
							.iBlue = 0,
							.iAlpha = 255,
							.fTime = 0.5,
							.iFadeFlags = FFADE_IN
			);
		}

		return;
	}

	pokemod_funcstart_debug( "StatusEffect" );

	g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_AMOUNT ]--;

	if ( g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_AMOUNT ] > 0 )
	{
		new Float:fNextEffect = 1.0;

		switch( iStatus )
		{
			case STATUS_BURN:
			{
				if ( entity_in_water( iPlayer ) )
				{
					g_iPlayerStatus[ iPlayer ][ STATUS_BURN ][ STATUS_AMOUNT ] = 0;
				}
				else
				{
					fNextEffect = SettingGetFloat( BURN_DELAY );

					new Int:iInflictor = g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_INFLICTOR ];

					SoundEmit( iPlayer, SOUND_BURN );

					new Coord:cOrigin[3];
					get_user_origin( iPlayer, cOrigin );

					EffectSprite( cOrigin, .iSprite = SPRITE_XFIRE, .fScale = 3.0, .iBrightness = 200 );

					message_begin( MSG_BROADCAST, SVC_TEMPENTITY );
					write_byte( TE_SMOKE );
					write_coord( cOrigin[0] );
					write_coord( cOrigin[1] );
					write_coord( cOrigin[2] + 100 );
					write_short( SPRITE_INDEX[ SPRITE_STEAM1 ] );
					write_byte( 60 );   // scale in 0.1's
					write_byte( 15 );   // framerate
					message_end();

					new Int:iBurnerID, CsTeams:iBurnedTeam = cs_get_user_team( iPlayer );

					new Int:iBurnDamage = SettingGetNum( BURN_DAMAGE );
					new Int:iBurnRadius = SettingGetNum( BURN_RADIUS );

					new Coord:cPlayerOrigin[3];
					LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALIVE )
					{
						get_user_origin( iPlayer, cPlayerOrigin );
						if ( get_distance( cOrigin, cPlayerOrigin ) <= iBurnRadius )
						{
							iBurnerID = ( iBurnedTeam == cs_get_user_team( iPlayer ) ) ? iInflictor : iPlayer;

							DamageFake( iPlayer, iBurnerID, iBurnDamage, "Burn", TYPE_FIRE, TYPE_NONE );

							if ( !g_iPlayerStatus[ iPlayer ][ STATUS_BURN ][ STATUS_AMOUNT ] )
							{
								StatusApply( iPlayer, iBurnerID, STATUS_BURN, 2 );
							}
						}
					}
				}
			}
			case STATUS_SLOW:
			{
				EventCurWeapon( iPlayer );
			}
			case STATUS_PARALYZE:
			{
				EntitySetVelocity( iPlayer, Float:{0.0,0.0,0.0} );
				EventCurWeapon( iPlayer );
			}
			case STATUS_POISON:
			{
				fNextEffect = SettingGetFloat( POISON_DELAY );

				if ( g_iPlayerStatus[ iPlayer ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] <= 0 )
				{
					EffectScreenFlash( iPlayer,
									.iRed = 255,
									.iGreen = 0,
									.iBlue = 255,
									.iAlpha = 150,
									.fTime = 1.0,
									.iFadeFlags = FFADE_MODULATE
					);
				}

				new Int:iInflictor = g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_INFLICTOR ];
				new Int:iPoisonDamage = SettingGetNum( POISON_DAMAGE );

				DamageFake( iPlayer, iInflictor, iPoisonDamage, "Poison", TYPE_POISON, TYPE_NONE );
			}
			case STATUS_ASLEEP:
			{
				EventCurWeapon( iPlayer );
				EffectScreenFlash( iPlayer,
								.iRed = 0,
								.iGreen = 0,
								.iBlue = 0,
								.iAlpha = 255,
								.fTime = fNextEffect,
								.iFadeFlags = FFADE_STAYOUT
				);
			}
			case STATUS_FROZEN:
			{
				fNextEffect = 0.1;
				if ( g_iPlayerStatus[ iPlayer ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] <= 0 )
				{
					EffectScreenFlash( iPlayer,
									.iRed = 0,
									.iGreen = 50,
									.iBlue = 150,
									.iAlpha = 100,
									.fTime = fNextEffect,
									.iFadeFlags = FFADE_MODULATE
					);
				}

				new Int:iInflictor = g_iPlayerStatus[ iPlayer ][ iStatus ][ STATUS_INFLICTOR ];
				new Int:iFrozenDamage = SettingGetNum( FROZEN_DAMAGE );

				DamageFake( iPlayer, iInflictor, iFrozenDamage, "Frozen", TYPE_ICE, TYPE_NONE );

				EventCurWeapon( iPlayer );
			}
			case STATUS_CONFUSE:
			{
				fNextEffect = SettingGetFloat( CONFUSE_DELAY );

				StatusFlinch( iPlayer );
			}
		}

		set_task( fNextEffect, "StatusEffect", 0, iParm, sizeof( iParm ) );
	}
	else
	{
		new const String:szStatusName[ PM_STATUS ][] = {
			"Burned",
			"Slowed",
			"Poisoned",
			"Asleep",
			"Frozen",
			"Confused",
			"Paralyzed"
		}
		DHudEventMessage( iPlayer, "You are no longer %s", szStatusName[ iStatus ] );

		switch( iStatus )
		{
			case STATUS_BURN:
			{
				emit_sound( iPlayer, CHAN_VOICE, gSounds[ SOUND_BURN ], VOL_NORM, ATTN_NORM, SND_STOP, PITCH_NORM );
			}
			case STATUS_SLOW, STATUS_FROZEN, STATUS_PARALYZE:
			{
				EventCurWeapon( iPlayer );
			}
			case STATUS_ASLEEP:
			{
				EventCurWeapon( iPlayer );

				EffectScreenFlash( iPlayer,
								.iRed = 0,
								.iGreen = 0,
								.iBlue = 0,
								.iAlpha = 255,
								.fTime = 0.5,
								.iFadeFlags = FFADE_IN
				);
			}
		}

		PlayerAddInfo( iPlayer, PINFO_STATUS_EFFECT, -1 );

		SkillCallType( CALL_STATUS_END, iPlayer );
	}

	PlayerHUD( iPlayer, iPlayer );

	pokemod_funcend_debug( "StatusEffect" );
}

PM_FUNC_NORM_ATTRIB StatusFlinch( Int:iPlayer )
{
	pokemod_funcstart_debug( "StatusFlinch" );

	new Vector:vAngles[ 3 ];
//	pev( iPlayer, pev_angles, vAngles );

	RandomVector( vAngles, 180.0 );
	vAngles[ 2 ] = 0.0;
//	vAngles[ 1 ] = random_float( -180.0, 180.0 );

//	set_pev( iPlayer, pev_angles, vAngles );
//	set_pev( iPlayer, pev_fixangle, 1 );
	set_pev( iPlayer, pev_punchangle, vAngles );

	client_print( iPlayer, print_center, "You flinched" );

	pokemod_funcend_debug( "StatusFlinch" );
}











